#include "struct.h"
#include "charFrequency.c"
#include "createHaffmanCode.c"
#include "zip.c"
#include "unzip.c"

void main(int arg, char *argv[]) {

    /*
    ** check params
    */
    if( argv[1] == NULL || argv[2] == NULL && argv[1][0] != 'h') {
        puts("need more value, `9z h` for more info");
    }


    int charbodyVariety = 0;
    char *table[256];
    CODING *p;
    int i;
    FILE *fp = fopen(argv[2], "rb");


    if( argv[1][0] == 'g' ) {

        /*
        ** compressed
        */

        TEXT *charFreq = NULL;
        charFreq = getNum(argv[2], &charbodyVariety);

        /* only one char type, haffman is useless */
        if( charbodyVariety < 2 ) {
            puts("Err for haffman. There is only one type char");
            return;
        }

        /* create haffmancode, p is pointing to charTree which is needed */
        p = createHaffmanCode(charFreq, charbodyVariety, 1);

        /* create hash for char to find its code */
        for(i = 0; i < charbodyVariety; i++ ) {
            table[(p + i)->charFreq.charbody] = (p + i)->code;
        }

        /* compress */
        zip(p, table, argv[2], charbodyVariety, charFreq);

        free(charFreq);
    }
    else if( argv[1][0] == 'u' ) {
        /* uncompress */
        HEAD *filehead = (HEAD *) calloc(sizeof(HEAD), 1);
        fread(filehead, sizeof(HEAD), 1, fp);

        /* that's because unsigned char can't bear 256 */
        if(filehead->variety == 0) {
            charbodyVariety = 256;
        }else{
            charbodyVariety = filehead->variety;
        }

        /* get head of compressed file, file head and char frequency */
        TEXT *charFreq = (TEXT *) calloc(sizeof(TEXT), charbodyVariety);
        fseek(fp, 16, SEEK_SET);
        fread(charFreq, sizeof(TEXT), charbodyVariety, fp);

        /* create haffman code by char frequency */
        p = createHaffmanCode(charFreq, charbodyVariety, 0);
        
        /* uncompressed */
        unzip(argv[2], filehead, p, charbodyVariety);
    }
    else if (argv[1][0] == 'h') {
        printf("\n***************\n9z [argv] [file]\nargv can be [g] [u]\ng: compress, u: uncompress\n[file] is file URL.\n***************\n");
    }
    else {
        puts("err args, `9z h` for more info");
    }
    fclose(fp);
}

/*
** Author: A9ia, finished: 2020.12.24 
** Many places of reference for this program come from https://blog.csdn.net/weixin_38214171/article/details/81626498
*/
